#include "base_puller.h"

namespace stream {



BaseDecoderManger::BaseDecoderManger(LogInfo* log_info): 
  log_ifo(log_info), stop_flag1(common::CameraClosed) {
    in_datas.resize(10, nullptr);
    in_loop_idx = 0;

}

BaseDecoderManger::~BaseDecoderManger() {}

int BaseDecoderManger::release_data(int source_id) {
  in_data_mtx.lock();
  if (decode_thread_map.count(source_id) > 0) {
    decode_thread_map.erase(source_id);
    std::cout << "BaseDecoderManger::release_data: " << source_id << std::endl;
  }
  in_data_mtx.unlock();
  return 0;
}
  
int BaseDecoderManger::set_data(int& set_idx, DecoderData* ddata) {
  set_idx = -1;

  int cur_idx = 0;
  in_data_mtx.lock();
  for (; cur_idx < in_datas.size(); cur_idx++) {
    if (in_datas[cur_idx] != nullptr) {continue;}
    // 分配当前数据包由哪个线程来长期解码  // 如果多个线程同时解码同一路视频数据会造成时间前后错乱
    if (decode_thread_map.count(ddata->source_id) == 0) {
      int choice_idx = -1;
      int min_chls = 1000;
      for (int idx = 0; idx < decoders.size(); idx++) {
        if (decoders[idx]->decode_width != ddata->width || decoders[idx]->decode_height != ddata->height) {continue;}
        if (decoders[idx]->decode_chls < min_chls) {
          min_chls = decoders[idx]->decode_chls;
          choice_idx = idx;
        }
      }

      if (choice_idx < 0) {
        in_data_mtx.unlock();
        std::cout << "error. decode_str " << ddata->width << "x" << ddata->height << std::endl;
        return -1;
      }
      decode_thread_map[ddata->source_id] = decoders[choice_idx]->thread_id;
      decoders[choice_idx]->decode_chls++;
    }

    in_datas[cur_idx] = ddata;
    in_datas[cur_idx]->thread_id = decode_thread_map[ddata->source_id];
    in_datas[cur_idx]->decode_id = set_data_idx;
    set_idx = set_data_idx;

    set_data_idx++;
    break;
  }
  if (set_data_idx > 1e6) {set_data_idx = 0;}
  in_data_mtx.unlock();

  return set_idx < 0 ? -1 : 0;
}

int BaseDecoderManger::get_data(int set_idx) {
  int ret = 0;
  while (true) {
    std::this_thread::sleep_for(milliseconds(3));
      
    out_data_mtx.lock();
    if (out_datas.count(set_idx) == 0) {out_data_mtx.unlock(); continue;}
    
    ret = out_datas[set_idx];
    out_datas.erase(set_idx);
    out_data_mtx.unlock();
    break;
  }

  // out_data_mtx.lock();
  // if (out_datas.count(set_idx) == 0) {out_data_mtx.unlock(); return -1;}
  
  // ret = out_datas[set_idx];
  // out_datas.erase(set_idx);
  // out_data_mtx.unlock();

  return ret;
}




}   // namespace stream
